﻿/* Copyright 2007-2008 dnAnalytics Project.
 *
 * Contributors to this file:
 * Marcus Cuda
 *
 * This file is part of dnAnalytics.  dnAnalytics is licensed under the 
 * Microsoft Public License. See License.txt for a complete copy of the
 * license.
 */

using System;

namespace dnAnalytics.Random
{
    internal class MklRandomNumberGenerator
    {
        private readonly double[] mBuffer = new double[Control.RandomNumberGeneratorBufferSize];
        private readonly int mBufferSize = Control.RandomNumberGeneratorBufferSize;
        private readonly uint mId;
        private int mCurrent;
        private bool mDisposed;

        public MklRandomNumberGenerator(MklRngMethod method, int seed)
        {
            mId = SafeNativeMethods.create_generator((int) method, (uint) seed);
            int status = SafeNativeMethods.call_generator(mId, mBufferSize, mBuffer);
        }

        ~MklRandomNumberGenerator()
        {
            if (!mDisposed)
            {
                Dispose();
            }
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (!mDisposed)
            {
                mDisposed = true;
                SafeNativeMethods.delete_generator(mId);
                GC.SuppressFinalize(this);
            }
        }

        /// <summary>
        /// Returns a random number between 0.0 and 1.0.
        /// </summary>
        /// <returns>
        /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
        /// </returns>
        public double Sample()
        {
            if (mCurrent < mBufferSize)
            {
                return mBuffer[mCurrent++];
            }
            int status = SafeNativeMethods.call_generator(mId, mBufferSize, mBuffer);
            mCurrent = 0;
            return mBuffer[mCurrent++];
        }
    }
}